package org.jeecg.modules.shiro.authc.interceptor;

import cn.hutool.core.io.IoUtil;
import cn.hutool.core.util.StrUtil;
import cn.hutool.json.JSONUtil;
import com.alibaba.fastjson.JSON;
import com.alibaba.fastjson.JSONObject;
import com.google.common.base.Charsets;
import com.google.common.collect.Lists;
import lombok.extern.slf4j.Slf4j;
import org.jeecg.common.api.vo.Result;
import org.jsoup.Jsoup;
import org.jsoup.safety.Whitelist;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.http.HttpMethod;
import org.springframework.stereotype.Component;
import org.springframework.web.servlet.HandlerInterceptor;

import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.io.PrintWriter;

/**
 * xss 请求拦截器
 *
 * @author: taoyan
 * @date: 2020年03月20日
 */
@Slf4j
@Component
public class XssInterceptor implements HandlerInterceptor {

    @Autowired
    private Whitelist whitelist;

    @Override
    public boolean preHandle(HttpServletRequest request, HttpServletResponse response, Object handler) throws Exception {
        if (!StrUtil.equalsIgnoreCase(request.getMethod(), HttpMethod.POST.name())) {
            return true;
        }
        boolean cond = false;
        try {
            //token失效抛出异常后程序继续进入了拦截器
            String body = "";
            if (request.getInputStream().isReady()) {
                body = IoUtil.read(request.getInputStream(), Charsets.UTF_8);
                if (JSONUtil.isJsonObj(body)) {
                    JSONObject object = JSON.parseObject(body);
                    for (Object value : object.values()) {
                        if (!Jsoup.isValid(value.toString(), whitelist)) {
                            cond = true;
                            break;
                        }
                    }
                }
            } else {
                String parameters = JSON.toJSONString(request.getParameterMap());
                if (JSONUtil.isJsonObj(parameters)) {
                    JSONObject object = JSON.parseObject(parameters);
                    for (Object value : object.values()) {
                        if (!Jsoup.isValid(value.toString(), whitelist)) {
                            cond = true;
                            break;
                        }
                    }
                }
            }
            if (cond) {
                response.setCharacterEncoding("UTF-8");
                response.setContentType("application/json; charset=utf-8");
                PrintWriter writer = response.getWriter();
                Result result = new Result();
                result.setSuccess(false);
                result.setMessage("非法参数");
                result.setCode(500);
                result.setResult(Lists.newArrayList());
                writer.print(JSON.toJSONString(result));
                writer.flush();
                writer.close();
                return false;
            }
            return true;
        } catch (Exception ex) {
            return true;
        }
    }
}
